package dao

import (
	"context"
	"mini-app/internal/dal"
	"mini-app/internal/define"
	"mini-app/internal/models"
	"time"

	"192.168.1.75/go-pkg/errorx"
)

type Advertisement struct{}

func (Advertisement) Create(ctx context.Context, query *dal.Query, ID, openID, customName, phoneNumber, deviceIDs, scheduleID, supportActivityID string, discountAmount float32, startTime, endTime int64) (err error) {
	o := query.Advertisement
	d := models.Advertisement{}
	d.ID = ID
	d.OpenID = openID
	d.CreatedAt = time.Now().Unix()
	d.PhoneNumber = phoneNumber
	d.CustomName = customName
	d.DeviceIDs = deviceIDs
	d.StartAt = startTime
	d.EndAt = endTime
	d.Status = define.AdOrderStatusUnpaid
	d.DiscountAmount = discountAmount
	d.ScheduleID = scheduleID
	d.SupportActivityID = supportActivityID
	d.ScheduleStatus = 1
	o.WithContext(ctx).Create(&d)
	return
}

func (Advertisement) OrderList(ctx context.Context, query *dal.Query, ID, openid string, orderStatus int, startTime, endTime int64, customeName, phoneNumber string, schedule_status int, supportActivityID string, page, limit int) (
	res []*models.Advertisement, total int64, err error,
) {
	o := query.Advertisement
	tx := o.WithContext(ctx)

	if ID != "" {
		tx = tx.Where(o.ID.Eq(ID))
	}
	if openid != "" {
		tx = tx.Where(o.OpenID.Eq(openid))
	}

	if orderStatus != 0 {
		tx = tx.Where(o.Status.Eq(orderStatus))
	}

	if startTime != 0 && endTime != 0 {
		tx = tx.Where(o.CreatedAt.Gte(startTime))
		tx = tx.Where(o.CreatedAt.Lte(endTime))
	}

	if customeName != "" {
		tx = tx.Where(o.CustomName.Eq(customeName))
	}
	if phoneNumber != "" {
		tx = tx.Where(o.PhoneNumber.Eq(phoneNumber))
	}
	if schedule_status > 0 {
		tx = tx.Where(o.ScheduleStatus.Eq(schedule_status))
	}
	if supportActivityID != "" {
		tx = tx.Where(o.SupportActivityID.Eq(supportActivityID))
	}
	// 按主订单进行分页
	// total 为主订单的总数
	var IDs []string
	total, _ = tx.Group(o.ID).Count()
	tx.Group(o.ID).Order(o.CreatedAt.Desc()).Offset(GetPageOffset(page, limit)).Limit(GetPageLimit(limit)).Pluck(o.ID, &IDs)

	// 返回每页主订单包含的子单
	tx1 := o.WithContext(ctx)
	res, _ = tx1.Where(o.ID.In(IDs...)).
		Order(o.CreatedAt.Desc(), o.ID.Desc()).
		Find()
	return
}

func (Advertisement) Detail(ctx context.Context, query *dal.Query, ID string) (
	res *models.Advertisement, err error,
) {
	o := query.Advertisement
	tx := o.WithContext(ctx)
	// if openid != "" {
	// 	tx = tx.Where(o.Openid.Eq(openid))
	// }
	if ID != "" {
		tx = tx.Where(o.ID.Eq(ID))
	}
	// if orderStatus != 0 {
	// 	tx = tx.Where(o.OrderStatus.Eq(orderStatus))
	// }
	res, err = tx.Select(o.ALL).Take()
	return
}
func (Advertisement) OrderStatusChange(ctx context.Context, query *dal.Query, ID string, orderStatus int) (err error) {
	if ID == "" {
		return
	}
	if orderStatus <= 0 {
		return
	}
	tx := query.Advertisement.WithContext(ctx)
	if ID != "" {
		tx = tx.Where(query.Advertisement.ID.Eq(ID))
	}
	res, _ := tx.UpdateColumn(query.Advertisement.Status, orderStatus)
	if res.RowsAffected <= 0 {
		return errorx.New("更新订单状态失败", -1)
	}
	return
}

func (Advertisement) OrderRemarkChange(ctx context.Context, query *dal.Query, ID string, status int, advertisementID, remark string) (err error) {
	if ID == "" {
		return
	}

	tx := query.Advertisement.WithContext(ctx)
	if ID != "" {
		tx = tx.Where(query.Advertisement.ID.Eq(ID))
	}
	if remark != "" {
		tx.UpdateColumn(query.Advertisement.Remark, remark)

	}
	if status != 0 {
		tx.UpdateColumn(query.Advertisement.Status, status)
	}
	if advertisementID != "" {
		tx.UpdateColumn(query.Advertisement.AdvertisementID, advertisementID)

	}

	return
}
func (Advertisement) OrderPayAmountChange(ctx context.Context, query *dal.Query, ID string, payAmount float32) (err error) {
	if ID == "" {
		return
	}

	tx := query.Advertisement.WithContext(ctx)
	if ID != "" {
		tx = tx.Where(query.Advertisement.ID.Eq(ID))
	}
	tx.UpdateColumn(query.Advertisement.PayAmount, payAmount)
	return
}
func (Advertisement) OrderPaidAmountChange(ctx context.Context, query *dal.Query, ID string, paidAmount float32) (err error) {
	if ID == "" {
		return
	}

	tx := query.Advertisement.WithContext(ctx)
	if ID != "" {
		tx = tx.Where(query.Advertisement.ID.Eq(ID))
	}
	tx.UpdateColumn(query.Advertisement.PaidAmount, paidAmount)
	return
}
func (Advertisement) SetPaidID(ctx context.Context, query *dal.Query, ID string, paidID string) (err error) {
	if ID == "" {
		return
	}

	tx := query.Advertisement.WithContext(ctx)
	if ID != "" {
		tx = tx.Where(query.Advertisement.ID.Eq(ID))
	}
	tx.UpdateColumn(query.Advertisement.PaidID, paidID)
	return
}

func (Advertisement) GetPaidID(ctx context.Context, query *dal.Query, ID string) (paidID string, err error) {
	if ID == "" {
		return
	}

	tx := query.Advertisement.WithContext(ctx)
	if ID != "" {
		tx = tx.Where(query.Advertisement.ID.Eq(ID))
	}

	ad, err := tx.First()
	if err != nil {
		return
	}
	return ad.PaidID, nil
}

// GetByNowTime retrieves advertisements active at the current time using query *dal.Query
func (Advertisement) GetByNowTime(ctx context.Context, query *dal.Query) (res []*models.Advertisement, err error) {
	o := query.Advertisement
	now := time.Now().Unix()
	tx := o.WithContext(ctx).
		Where(o.StartAt.Lte(now)).
		Where(o.EndAt.Gte(now)).
		Where(o.Status.Eq(define.AdOrderStatusPaid))
	res, err = tx.Find()
	return
}

// GetLastOrderByOpenID retrieves the most recent order for a given openID
func (Advertisement) GetLastOrderByOpenID(ctx context.Context, query *dal.Query, openID string) (res *models.Advertisement, err error) {
	if openID == "" {
		return nil, nil
	}

	o := query.Advertisement
	tx := o.WithContext(ctx).
		Where(o.OpenID.Eq(openID)).
		Order(o.CreatedAt.Desc()).
		Limit(1)

	res, err = tx.First()
	return
}

func (Advertisement) DetailByScheduleID(ctx context.Context, query *dal.Query, ID string) (
	res *models.Advertisement, err error,
) {
	o := query.Advertisement
	tx := o.WithContext(ctx)
	// if openid != "" {
	// 	tx = tx.Where(o.Openid.Eq(openid))
	// }
	if ID != "" {
		tx = tx.Where(o.ScheduleID.Eq(ID))
	}
	// if orderStatus != 0 {
	// 	tx = tx.Where(o.OrderStatus.Eq(orderStatus))
	// }
	res, err = tx.Select(o.ALL).Take()
	return
}

func (Advertisement) OrderScheduleStatusChange(ctx context.Context, query *dal.Query, ID string, scheduleStatus int) (err error) {
	if ID == "" {
		return errorx.New("更新订单计划状态失败,ID不能为空", -1)
	}
	if scheduleStatus <= 0 {
		return errorx.New("更新订单计划状态失败,状态<=0", -1)

	}
	tx := query.Advertisement.WithContext(ctx)
	if ID != "" {
		tx = tx.Where(query.Advertisement.ID.Eq(ID))
	}

	res, _ := tx.UpdateColumn(query.Advertisement.ScheduleStatus, scheduleStatus)
	if res.RowsAffected <= 0 {
		return errorx.New("更新订单计划状态失败", -1)
	}
	return
}
